#include "freertos/FreeRTOS.h"
#include "esp_log.h"
#include "esp_err.h"
#include "video_ui.h"
#include "main_ui.h"
#include "audio.h"
#include "sd_card.h"
#include "avifile.h"
#include "avi_player.h"
#include "file_iterator.h"
#include "pca9557pw.h"
#include "jpeg_decoder.h"
#include "app_sr.h"
#include "ui_setting.h"
// 声明字体
LV_FONT_DECLARE(myFont);
LV_FONT_DECLARE(lv_font_montserrat_14);
static const char *TAG = "video_ui";
static lv_obj_t *video_img;        // 视频显示对象
static avi_player_handle_t handle; // 视频播放器句柄
static char filename[128];
static i2s_chan_handle_t aduio_tx_chan; // 音频播放通道
// 文件迭代器实例
static file_iterator_instance_t *file_iterator = NULL;
static lv_img_dsc_t img_dsc;// 图像描述符
static bool is_set_i2s_fs=false;// 图像描述符

#define VIDEO_FILE_PATH SD_MOUNT_POINT "/video" // 视频文件路径sd
#define FRAME_BUFFER_SIZE (320 * 240 * 2)         // 屏幕数据大小(320*240*RGB565)

// 视频帧结构
typedef struct {
    uint8_t *data;
    size_t size;
    int width;
    int height;
} video_frame_t;

static video_frame_t current_frame = { 0 };

void exit_video_ui(lv_obj_t *root)
{
    if (!root) {
        return;
    }
    pa_en(0); // 关闭功放
    // 停止播放器
    if (handle) {
        avi_player_play_stop(handle);
        avi_player_deinit(handle);
        handle = NULL;
    }

    // 释放帧数据内存
    if (current_frame.data) {
        free(current_frame.data);
        current_frame.data = NULL;
        current_frame.size = 0;
    }

    // 释放文件迭代器
    if (file_iterator) {
        //file_iterator_delete(file_iterator);
        file_iterator = NULL;
    }

    bsp_sdcard_unmount();    // 卸载SD卡
    switch_to_main_screen(); // 切换到主界面
    if (img_dsc.data)
    {
        free(img_dsc.data);
        img_dsc.data = NULL;
    }
    if (is_set_i2s_fs) {
         app_sr_init();//重新初始化语音识别
    }
        lv_obj_del(root); // 删除UI对象


}

// 手势事件回调
static void event_handler(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);

    if (code == LV_EVENT_GESTURE) {
        lv_indev_t *indev = lv_indev_get_act();
        if (!indev)
            return;

        lv_dir_t dir = lv_indev_get_gesture_dir(indev);

        // 保留右划检测
        if (dir == LV_DIR_RIGHT || dir == LV_DIR_TOP) {
            exit_video_ui(e->target);
        }
    }
}

/*
 *@brief 视频播放回调函数
*/
void video_write(frame_data_t *data, void *arg)
{
    // ESP_LOGI(TAG, "Video write: %d bytes, width: %d, height: %d",
    //          data->data_bytes, data->video_info.width, data->video_info.height);
    if (data->video_info.width>320||data->video_info.height>240)
    {
        //todo
        /*buf装不下，需要重新申请内存*/
        ESP_LOGE(TAG, "Video size is too large, width: %d, height: %d", data->video_info.width, data->video_info.height);
        return;
    }
        // JPEG图像解码配置结构体
    esp_jpeg_image_cfg_t jpeg_cfg = {
        // 输入数据缓冲区指针，指向待解码的JPEG图像数据
        .indata = (uint8_t *)data->data,

        // 输入数据的大小（字节数）
        .indata_size = data->data_bytes,

        // 输出数据缓冲区指针，用于存储解码后的图像数据
        .outbuf = (uint8_t *)img_dsc.data,

        // 输出缓冲区的大小（字节数）
        .outbuf_size = FRAME_BUFFER_SIZE,

        // 输出图像格式，此处设置为RGB565格式（16位色彩，红5位，绿6位，蓝5位）
        .out_format = JPEG_IMAGE_FORMAT_RGB565,

        // 输出图像缩放比例，此处设置为不缩放（保持原始尺寸）
        .out_scale = JPEG_IMAGE_SCALE_0,

        // 标志位配置
        .flags = {
            // 颜色字节交换标志，设置为1表示交换颜色字节顺序
            // 这通常用于调整字节序以匹配显示设备的预期格式
            .swap_color_bytes = 1,
        }
    };

    // JPEG解码输出结构体，用于接收解码后的图像信息
    esp_jpeg_image_output_t outimg;

    // 执行JPEG解码操作，使用上述配置进行解码
    // 解码结果将存储在outimg结构体中
    esp_err_t ret = esp_jpeg_decode(&jpeg_cfg, &outimg);
    if (ret!= ESP_OK)
    {
        ESP_LOGE(TAG, "JPEG decode failed, ret: %d", ret);
    } else { // 创建LVGL图像描述符
        img_dsc.header.cf = LV_IMG_CF_TRUE_COLOR;
        img_dsc.header.always_zero = 0;
        img_dsc.header.reserved = 0;
        img_dsc.header.w = outimg.width;
        img_dsc.header.h = outimg.height;
        img_dsc.data_size = outimg.output_len;
        //img_dsc.data = icon_2048_map;
        // 更新图像显示
        lv_img_set_src(video_img, &img_dsc);
    }
}

/*
 *@brief 音频播放回调函数
*/
void audio_write(frame_data_t *data, void *arg)
{
    size_t bytes_write = 0;
    i2s_channel_write(aduio_tx_chan, data->data, data->data_bytes, &bytes_write, pdMS_TO_TICKS(500));
   // ESP_LOGI(TAG, "Audio write: %d, bytes_write: %d", data->data_bytes, bytes_write);
}
static void user_enter_cb(void)
{
    // 播放视频
    if (avi_player_play_from_file(handle, filename) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to play video");
        lv_obj_t *label_err = lv_label_create(video_img);
        lv_label_set_text(label_err, "视频播放失败");
        lv_obj_set_style_text_color(label_err, lv_color_white(), 0);
        lv_obj_set_style_text_font(label_err, &myFont, 0);
        lv_obj_align(label_err, LV_ALIGN_CENTER, 0, 0);
    }
}
static void user_exit_cb(void)
{
    lv_obj_t *parent = lv_obj_get_parent(video_img);
    exit_video_ui(parent);
}
    /*
 *@brief 音频设置时钟回调函数
*/
void audio_set_clock(uint32_t rate, uint32_t bits_cfg, uint32_t ch, void *arg)
{
    if (i2s_fs_is_default(rate, bits_cfg, ch))
    {
        if (!is_set_i2s_fs) {
            if (get_voice_control()) {
                ESP_LOGI(TAG, "_audio_player_std_clock rate:%d ,bits_cfg:%d,ch:%d ", rate, bits_cfg, ch);
                avi_player_play_stop(handle); // 暂停播放
                reminder_voice_clash_ui(rate, bits_cfg, ch, user_enter_cb, user_exit_cb);
                is_set_i2s_fs = true;
                return;
            }
        }
    }


    ESP_LOGI(TAG, "Audio set clock, rate %" PRIu32 ", bits %" PRIu32 ", ch %" PRIu32 "", rate, bits_cfg, ch);
    bsp_codec_set_fs(rate, bits_cfg, ch);
}

/*
 *@brief 播放结束回调函数
*/
void avi_play_end(void *arg)
{
    ESP_LOGI(TAG, "Play end");
    file_iterator_next(file_iterator);
    int index = file_iterator_get_index(file_iterator);
    //todo 做参数判断
    ESP_LOGI(TAG, "playing index '%d'", index);
    file_iterator_get_full_path_from_index(file_iterator, index, filename, sizeof(filename));
    avi_player_play_from_file(handle, filename);
    // end_play = true;
}

/* 
 * @brief:创建视频UI
*/
lv_obj_t *create_video_ui(void)
{
    // 创建根容器（全屏黑色背景）
    lv_obj_t *root = lv_obj_create(NULL);
    if (!root) {
        return NULL;
    }
    is_set_i2s_fs = false;
    lv_obj_set_size(root, lv_pct(100), lv_pct(100));
    lv_obj_set_style_bg_color(root, lv_color_black(), 0);
    lv_obj_add_event_cb(root, event_handler, LV_EVENT_GESTURE, NULL);
    esp_err_t ret = bsp_sdcard_mount(); // 挂载SD卡
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "SD card mount failed");
        // 创建错误提示界面
        lv_obj_t *label_err = lv_label_create(root);
        lv_label_set_text(label_err, "SD卡挂载失败");
        lv_obj_set_style_text_color(label_err, lv_color_white(), 0);
        lv_obj_set_style_text_font(label_err, &myFont, 0);
        lv_obj_align(label_err, LV_ALIGN_CENTER, 0, 0);
        return root;
    }



    // 创建视频显示区域
    video_img = lv_img_create(root);
    lv_obj_set_size(video_img, lv_pct(100), lv_pct(100));
    lv_obj_align(video_img, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_bg_color(video_img, lv_color_black(), 0);

    // 初始化AVI播放器
    avi_player_config_t config = {
        .buffer_size = 60 * 1024, // 60k
        .audio_cb = audio_write,
        .video_cb = video_write,
        .audio_set_clock_cb = audio_set_clock,
        .avi_play_end_cb = avi_play_end,
        .stack_size = 4096,
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
        .stack_in_psram = false,
#endif
    };

    aduio_tx_chan = get_i2s_tx_chan();
    if (avi_player_init(config, &handle) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to initialize AVI player");
        lv_obj_t *label_err = lv_label_create(root);
        lv_label_set_text(label_err, "播放器初始化失败");
        lv_obj_set_style_text_color(label_err, lv_color_white(), 0);
        lv_obj_set_style_text_font(label_err, &myFont, 0);
        lv_obj_align(label_err, LV_ALIGN_CENTER, 0, 0);
        return root;
    }

    // 初始化文件迭代器
    file_iterator = file_iterator_new(VIDEO_FILE_PATH);
    if (!file_iterator) {
        ESP_LOGE(TAG, "Failed to create file iterator");
        lv_obj_t *label_err = lv_label_create(root);
        lv_label_set_text(label_err, "无法读取视频文件");
        lv_obj_set_style_text_color(label_err, lv_color_white(), 0);
        lv_obj_set_style_text_font(label_err, &myFont, 0);
        lv_obj_align(label_err, LV_ALIGN_CENTER, 0, 0);
        return root;
    }
    // 获取第一个视频文件
    // 从文件迭代器获取完整文件路径
    int retval = file_iterator_get_full_path_from_index(file_iterator, 0, filename, sizeof(filename));
    if (retval == 0) {
        ESP_LOGE(TAG, "No video files found");
        lv_obj_t *label_err = lv_label_create(root);
        lv_label_set_text(label_err, "未找到视频文件");
        lv_obj_set_style_text_color(label_err, lv_color_white(), 0);
        lv_obj_set_style_text_font(label_err, &myFont, 0);
        lv_obj_align(label_err, LV_ALIGN_CENTER, 0, 0);
        return root;
    }

    ESP_LOGI(TAG, "Playing video: %s", filename);

    /*******************************/
    pa_en(1); // 使能功放
    bsp_codec_volume_set(80,NULL); // 设置音量
    img_dsc.data = malloc(FRAME_BUFFER_SIZE); //屏幕像素为320*240，RGB565格式
    // 开始播放视频
    if (avi_player_play_from_file(handle, filename) != ESP_OK) {
        ESP_LOGE(TAG, "Failed to play video");
        lv_obj_t *label_err = lv_label_create(root);
        lv_label_set_text(label_err, "视频播放失败");
        lv_obj_set_style_text_color(label_err, lv_color_white(), 0);
        lv_obj_set_style_text_font(label_err, &myFont, 0);
        lv_obj_align(label_err, LV_ALIGN_CENTER, 0, 0);
    }

    return root;
}